#include "lh_widget.h"


static LH_WIDGET   *LHDialogBuff[LH_DIALOG_BUFF_NUM] = {0};     
static LH_WIDGET   *LHFocDialog = LH_NULL;      
static LH_U16      LHDialogNum = 0;             
LH_U16 LH_GUIRunEve;                            



void FreeLHDialogBuff(LH_WIDGET *dialog)
{
    LH_U16 i1 = 0;
    
    for(; i1 < LHDialogNum; i1 ++)
        if(LHDialogBuff[i1]->WidSeq == dialog->WidSeq)
            break;
        
    for(; i1 < LHDialogNum-1; i1 ++)
        LHDialogBuff[i1] = LHDialogBuff[i1+1];
    
    LHDialogNum --;
}


LH_WIDGET *LH_CreatDialog(WID_GATHER *widgather, LH_U16 widnum, LH_CALLBACK *callback)
{
    LH_U16 count;
    LH_WIDGET *link_head = LH_NULL, *link_help1 = LH_NULL, *link_help2 = LH_NULL;
    
    for(count = 0; count < widnum; count ++)
    { 
        link_help1 = GetWidBuffUnit();                          
        if(link_help1 == LH_NULL)   return LH_NULL;             
        link_help1->WidgetType = widgather->WidgetType;         
        link_help1->WidSeq = widgather->WidSeq;                 
        link_help1->WidFlags = widgather->WidFlags;             
        if (link_help1->WidgetType == LH_DIALOG)                
        {
            link_help1->FatherWidSeq = FATHER_NULL;             
            link_help1->Axis_X = widgather->Axis_X;             
            link_help1->Axis_Y = widgather->Axis_Y;             
            if(widnum > 1)                                      
                link_help1->WidFlags |= LH_CLDWID;              
            else
                link_help1->WidFlags &= ~LH_CLDWID;             
        }
        else
        {
            link_help1->DialogLayer = count;                            
            link_help1->FatherWidSeq = link_head->WidSeq;               
            link_help1->Axis_X = widgather->Axis_X+link_head->Axis_X;   
            link_help1->Axis_Y = widgather->Axis_Y+link_head->Axis_Y;   
            link_help1->WidFlags &= ~LH_WIDFOC;                         
            link_help1->WidFlags &= ~LH_CLDWID;                         
        }
        link_help1->WidFlags &= ~LH_CLDFOC;                     
        link_help1->WidFlags |= LH_WIDREDR;                     
        link_help1->WidColor = LH_WHITE;                        
        LH_MemWidAllot(link_help1, widgather);                  
        link_help1->Path1           = widgather->Path1;         
        link_help1->Path2           = widgather->Path2;         
        
        GetWidgetLenWid(&link_help1->Length, &link_help1->Width, link_help1->Path1);
        LH_WidEvAssign(link_help1);                 
        link_help1->CallBack       = callback;      
        link_help1->NextWidget     = LH_NULL;       
        
        if(link_help2 == LH_NULL) 
        {
            link_head = link_help1;                 
            link_head->LastWidget  = LH_NULL;       
        }
        else        
        {            
            link_help1->LastWidget = link_help2;    
            link_help2->NextWidget = link_help1;    
        }
        link_help2 = link_help1;                    
        widgather ++;                               
    }
    link_help1->NextWidget = LH_NULL;               
    
    LHDialogBuff[LHDialogNum] = link_head;          
    LHDialogBuff[LHDialogNum]->WidFlags |= LH_WIDFOC;           
    if (LHDialogNum > 0)                            
        LHDialogBuff[LHDialogNum-1]->WidFlags &= ~LH_WIDFOC;    
    LHDialogBuff[LHDialogNum]->DialogLayer = LHDialogNum;       
    LHFocDialog = link_head;                        
    LHDialogNum ++;                                 

    return link_head;                               
}



void LH_MemWidAllot(LH_WIDGET *widget, WID_GATHER *widgather)
{
    if (widget->WidgetType == LH_DIALOG)                
        widget->PData = GetS16Unit(widget);             
    else if (widget->WidgetType == LH_RADIO)            
    {
        widget->PData = GetS8Unit(widget);              
        *(LH_S8 *)widget->PData = RADIO_NO;             
    }
    else if (widget->WidgetType == LH_LABEL)            
    {
        widget->PData = GetS8Unit(widget);              
        StringCopy(widget->PData, widgather->PData);    
    }
    else if (widget->WidgetType == LH_GRAPH)            
    {
        widget->PData = GetS16Unit(widget);             
        *( LH_S16 *)widget->PData      = 0;             
        *((LH_S16 *)widget->PData + 1) = 0;             
        *((LH_S16 *)widget->PData + 2) = LH_GRAPH_UNIT_SIZE/3;  
        *((LH_S16 *)widget->PData + 3) = 0;             
        GraphPdataInit(widget);                         
    }     
    else if (widget->WidgetType == LH_EDIT)             
    {
        widget->PData = GetS8Unit(widget);              
        StringCopy(widget->PData, widgather->PData);    
    }
    else if (widget->WidgetType == LH_MULTIEDIT)         
    {
        widget->PData = GetS8Unit(widget);              
        StringCopy(widget->PData, widgather->PData);    
    }
    else      
        widget->PData = (LH_S8 *)widgather->PData;      
}



void LH_WidEvAssign(LH_WIDGET *widget)
{
    if (widget->WidgetType == LH_DIALOG)     widget->WidEv = LH_DialogEve;      
    if (widget->WidgetType == LH_BUTTON)     widget->WidEv = LH_ButtonEve;
    if (widget->WidgetType == LH_LABEL)      widget->WidEv = LH_LabelEve;
    if (widget->WidgetType == LH_RADIO)      widget->WidEv = LH_RadioEve;
    if (widget->WidgetType == LH_GRAPH)      widget->WidEv = LH_GraphEve;
    if (widget->WidgetType == LH_EDIT)       widget->WidEv = LH_EditEve;
    if (widget->WidgetType == LH_MULTIEDIT)  widget->WidEv = LH_MultiEditEve;
}



void LH_WidgetScan(void)
{
    LH_WIDGET *DilgFoc = LH_NULL;   
    LH_WIDGET *DilgToc = LH_NULL;   
    LH_WIDGET *DilgRem = LH_NULL;   

    if(TcEve.TocSyn == TOC_SYN_YES) 
    {
        DilgFoc = GetChildFather(LHFocDialog);  
        RedrawCrAnNeWid(DilgFoc);               
        if (TcEve.NowEvent != TOUCH_NOT)        
        {
            DilgToc = GetTocDig(DilgFoc);       
            if (DilgToc == DilgFoc)             
            {
                DilgRem = DilgFoc;              
                while(DilgFoc->NextWidget != LH_NULL)
                    DilgFoc = DilgFoc->NextWidget;  
                do
                {
                    
                    if ( (TcEve.NowX >= DilgFoc->Axis_X) 
                      && (TcEve.NowX <= DilgFoc->Axis_X+DilgFoc->Length) 
                      && (TcEve.NowY >= DilgFoc->Axis_Y) 
                      && (TcEve.NowY <= DilgFoc->Axis_Y+DilgFoc->Width) && (DilgFoc->WidFlags & LH_WIDREEV) )
                    {
                        
                        if ( (TcEve.NowEvent == TOUCH_STOP) && (DilgFoc->WidFlags & LH_WIDFOC) )
                        {
                            DilgFoc->WidFlags |= LH_WIDREDR;    
                            SetWidTopRedraw(DilgFoc);           
                        }
                        
                        if (TcEve.NowEvent == TOUCH_START)  
                        {                  
                            if ((DilgFoc->WidFlags & LH_WIDFOC) == 0)
                                LH_SetWidgetFocus(DilgFoc);     
                            DilgFoc->WidFlags |= LH_WIDREDR;    
                            SetWidTopRedraw(DilgFoc);           
                        }
                        
                        if (DilgFoc->WidFlags & LH_WIDFOC)
                        {
                            RedrawCrAnNeWid(DilgFoc);           
                            LH_GUIRunEve = TcEve.NowEvent;      
                            DilgFoc->CallBack(DilgFoc->WidSeq); 
                            ClrTocSyn();                        
                            return;                             
                        }
                    }
                    DilgFoc = DilgFoc->LastWidget;              
                }
                while(DilgFoc->WidgetType != LH_DIALOG);        
                
                
                if ( (TcEve.NowEvent == TOUCH_START) && ((DilgRem->WidFlags & LH_WIDFOC) == 0) )
                    LH_SetWidgetFocus(DilgRem);                     
                if ( DilgRem->WidFlags & LH_WIDFOC)                 
                {                    
                    LH_GUIRunEve = TcEve.NowEvent;                  
                    DilgRem->CallBack(DilgRem->WidSeq);             
                }
                else                                                
                {
                    if (TcEve.NowEvent == TOUCH_CATCH)
                    {
                        LH_GUIRunEve = TOUCH_CAT_NOT;               
                        LHFocDialog->CallBack(LHFocDialog->WidSeq); 
                    }
                    else if (TcEve.NowEvent == TOUCH_STOP)          
                    {
                        LH_GUIRunEve = TOUCH_LEV_NOT;               
                        LHFocDialog->WidFlags |= LH_WIDREDR;        
                        SetWidTopRedraw(LHFocDialog);               
                        RedrawCrAnNeWid(LHFocDialog);               
                        LHFocDialog->CallBack(LHFocDialog->WidSeq); 
                    }
                }
                
                CleanFormAlterFlag();   
            }
            else
            {
                if(DilgToc != LH_NULL)          
                {
                    LH_SetWidgetFocus(DilgToc); 
                    SetFormRedraw(DilgToc);
                }
                
                SetFormAlterFlag();     
            }
        }
        else
            CleanFormAlterFlag();       
        ClrTocSyn();    
    }
}



LH_WIDGET *GetTocDig(LH_WIDGET *dialog)
{
    LH_WIDGET *DilgFoc = LH_NULL;
    LH_U16  RemDigLayer = dialog->DialogLayer;
    LH_U16  Count1 = 0;
    
    if ( (TcEve.NowX >= dialog->Axis_X) && (TcEve.NowX <= dialog->Axis_X+dialog->Length) 
      && (TcEve.NowY >= dialog->Axis_Y) && (TcEve.NowY <= dialog->Axis_Y+dialog->Width) )
        return dialog;
    else
    {
        if(RemDigLayer == 0)
            return LH_NULL;
        do
        {
            RemDigLayer --;
            
            for(Count1 = 0; Count1 < LHDialogNum; Count1 ++)
            {
                if(LHDialogBuff[Count1]->DialogLayer == RemDigLayer)
                {
                    DilgFoc = LHDialogBuff[Count1];
                    if ( (TcEve.NowX >= DilgFoc->Axis_X) && (TcEve.NowX <= DilgFoc->Axis_X+DilgFoc->Length) 
                      && (TcEve.NowY >= DilgFoc->Axis_Y) && (TcEve.NowY <= DilgFoc->Axis_Y+DilgFoc->Width) )
                        return DilgFoc;
                    break;
                }
            }
        }
        while(RemDigLayer > 0);
        
        return LH_NULL;
    }
}



LH_WIDGET *GetChildFather(LH_WIDGET *child)
{
    LH_U16 count1 = 0;
    if(child->WidgetType == LH_DIALOG)  
        return child;
    for(; count1 < LHDialogNum; count1 ++)
    {
        if(LHDialogBuff[count1]->WidSeq == child->FatherWidSeq)
            return LHDialogBuff[count1];
    }
    return LH_NULL; 
}



LH_WIDGET *GetDialogWid(LH_WIDGET *dialog, LH_U16 WidSeq)
{
    LH_WIDGET *SrWidget = dialog;

    while(SrWidget != LH_NULL)
    {
        if(SrWidget->WidSeq == WidSeq)
            return SrWidget;
        SrWidget = SrWidget->NextWidget;
    }
    return LH_NULL;
}



void SetWidgetRedraw(LH_WIDGET *widget)
{
    widget->WidFlags |= LH_WIDREDR;
}



void CleanWidgetRedraw(LH_WIDGET *widget)
{
    widget->WidFlags &= ~LH_WIDREDR;
}


void SetWidgetWidReEv(LH_WIDGET *widget)
{
    widget->WidFlags |= LH_WIDREEV;
}

void CleanWidgetWidReEv(LH_WIDGET *widget)
{
    widget->WidFlags &= ~LH_WIDREEV;
}



void SetWidTopRedraw(LH_WIDGET *widget)
{
    LH_WIDGET *TopWid = widget->NextWidget;
    
    if(TopWid == LH_NULL)
        return;
    else
    {
        while(TopWid != LH_NULL)
        {
            if ( (TopWid->Axis_X >= widget->Axis_X) && (TopWid->Axis_X <= widget->Axis_X+widget->Length) 
              && (TopWid->Axis_Y >= widget->Axis_Y) && (TopWid->Axis_Y <= widget->Axis_Y+widget->Width) )
                TopWid->WidFlags |= LH_WIDREDR;
            
            TopWid = TopWid->NextWidget;
        }
    }
}



void SetFormRedraw(LH_WIDGET *widget)
{
    LH_WIDGET *Father = GetChildFather(widget);
    
    do
    {
        Father->WidFlags |= LH_WIDREDR;
        Father = Father->NextWidget;
    }
    while(Father != NULL);
}



void CleanFormRedraw(LH_WIDGET *widget)
{
    LH_WIDGET *Father = GetChildFather(widget);
    
    do
    {
        Father->WidFlags &= ~LH_WIDREDR;
        Father = Father->NextWidget;
    }
    while(Father != NULL);
}



void RedrawCrAnNeWid(LH_WIDGET *widget)
{
    LH_WIDGET *SrWidget = widget;
    do
    {
        if (SrWidget->WidFlags & LH_WIDREDR)
        {
            LH_GUIRunEve = REDRAW_PREF;
            SrWidget->CallBack(SrWidget->WidSeq);
            SrWidget->WidEv(SrWidget);        
            LH_GUIRunEve = REDRAW_LATER;
            SrWidget->CallBack(SrWidget->WidSeq);
            SrWidget->WidFlags &= ~LH_WIDREDR;
        }
        SrWidget = SrWidget->NextWidget;      
    }
    while(SrWidget != LH_NULL);   
}



void LH_SetWidgetFocus(LH_WIDGET *widget)
{
    LH_U16 RemLayer;
    LHFocDialog->WidFlags &= ~LH_WIDFOC;                    
    
    if (LHFocDialog->WidgetType == LH_DIALOG)               
    {
        if (widget->WidgetType == LH_DIALOG)                
        {                                                   
            RemLayer = LHFocDialog->DialogLayer;            
            LHFocDialog->DialogLayer = widget->DialogLayer; 
            widget->DialogLayer = RemLayer;   
            LHFocDialog->WidFlags &= ~LH_CLDFOC;            
            widget->WidFlags &= ~LH_CLDFOC;                 

            SetFormAlterFlag();     
        }
        else
        {
            if (LHFocDialog->WidSeq == widget->FatherWidSeq)
            {
                LHFocDialog->WidFlags |= LH_CLDFOC;         
                CleanFormAlterFlag();   
            }
            else    
            {
                LH_WIDGET *RemWid;
                LHFocDialog->WidFlags &= ~LH_CLDFOC;                
                RemWid = GetChildFather(widget);                    
                RemWid->WidFlags |= LH_CLDFOC;                      
                RemLayer = LHFocDialog->DialogLayer;                
                LHFocDialog->DialogLayer = RemWid->DialogLayer;     
                RemWid->DialogLayer = RemLayer;   
                
                SetFormAlterFlag();     
            }                
        }     
    }
    else                                                            
    {
        if (widget->WidgetType == LH_DIALOG)                        
        {
            if (LHFocDialog->FatherWidSeq == widget->WidSeq)        
            {
                widget->WidFlags |= LH_CLDFOC;                      
                CleanFormAlterFlag();   
            }
            else        
            {        
                LH_WIDGET *RemWid;                
                RemWid = GetChildFather(LHFocDialog);               
                RemWid->WidFlags &= ~LH_CLDFOC;                     
                RemLayer = RemWid->DialogLayer;                     
                RemWid->DialogLayer = widget->DialogLayer;          
                widget->DialogLayer = RemLayer;  
                
                SetFormAlterFlag();     
            }    
        }
        else            
        {
            LH_WIDGET *RemWidLst;
            LH_WIDGET *RemWidNow;
            RemWidLst = GetChildFather(LHFocDialog);
            RemWidNow = GetChildFather(widget);
            
            if (RemWidLst->FatherWidSeq == RemWidNow->FatherWidSeq) 
            {
                CleanFormAlterFlag();   
            }
            else    
            {
                RemWidLst->WidFlags &= ~LH_CLDFOC;                  
                RemWidNow->WidFlags |= LH_CLDFOC;                   
                RemLayer = RemWidLst->DialogLayer;                  
                RemWidLst->DialogLayer = RemWidNow->DialogLayer;    
                RemWidNow->DialogLayer = RemLayer;   
                
                SetFormAlterFlag();     
            }
        }
    }
                
    widget->WidFlags |= LH_WIDFOC;          
    LHFocDialog = widget;                   
}



void SetWidColor(LH_WIDGET *widget, LH_U16 color)
{
    widget->WidColor = color;
}



LH_U16 GetWidColor(LH_WIDGET *widget)
{
    return widget->WidColor;
}



void SetStrWidPData(LH_WIDGET *widget, LH_S8 *pbuff)
{
    StringCopy((LH_S8 *)widget->PData, pbuff);
}



void SetPDataInt(LH_WIDGET *widget, LH_U64 num, LH_U16 leng, LH_U16 dotp)
{
    LH_S8  StoreBuff[20];
    
    StingConvNum(num, leng, dotp, StoreBuff);             
    SetStrWidPData(widget, StoreBuff);          
    widget->WidFlags |= LH_WIDREDR;
}









